package com.java.common.handler;

import com.java.common.constants.ResultCodeEnum;
import com.java.common.exception.RException;
import com.java.common.util.ExceptionUtil;
import com.java.common.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.naming.SizeLimitExceededException;

/**
 * @author jiangli
 * @since 2019/6/25
 * 统一异常处理器
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

	/**
	 * 自定义异常
	 */
	@ExceptionHandler(RException.class)
	public R error(RException e){
		log.error(ExceptionUtil.getMessage(e));
		return R.error(e.getCode(),e.getMessage());
	}

	/**
	 * 参数校验Exception
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public Object validExceptionHandler(MethodArgumentNotValidException e){
		FieldError fieldError = e.getBindingResult().getFieldError();
		assert fieldError != null;
		log.error(fieldError.getField() + ":" + fieldError.getDefaultMessage());
		// 将错误的参数的详细信息封装到统一的返回实体
		return R.error(fieldError.getDefaultMessage());
	}

	/**
	 * 参数校验Exception
	 */
	@ExceptionHandler(BindException.class)
	public Object validExceptionHandler(BindException e){
		FieldError fieldError = e.getBindingResult().getFieldError();
		assert fieldError != null;
		log.error(fieldError.getField() + ":" + fieldError.getDefaultMessage());
		return R.error(fieldError.getDefaultMessage());
	}

	/**
	 * Sql语法错误
	 */
	@ExceptionHandler(BadSqlGrammarException.class)
	public R error(BadSqlGrammarException e){
		log.error(e.getMessage());
		return R.e(ResultCodeEnum.BAD_SQL_GRAMMAR);
	}

	@ExceptionHandler(HttpMessageNotReadableException.class)
	public R error(HttpMessageNotReadableException e){
		log.error(e.getMessage());
		return R.e(ResultCodeEnum.JSON_PARSE_ERROR);
	}


	@ExceptionHandler(SizeLimitExceededException.class)
	public R error(SizeLimitExceededException e){
		log.error(e.getMessage());
		return R.e(ResultCodeEnum.FILE_UPLOAD_ERROR);
	}

	@ExceptionHandler(Exception.class)
	public R error(Exception e){
		log.error(e.getMessage());
		return R.error();
	}
}
